package com.jxtc.enterprise.admin.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jxtc.enterprise.common.entity.*;
import com.jxtc.enterprise.common.exception.ModifyFailureException;
import com.jxtc.enterprise.common.mapper.*;
import com.jxtc.enterprise.common.utils.DateTimeUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class AdminTenantManageService {

    private final TenantMapper tenantMapper;
    private final CompanyMapper companyMapper;
    private final FoodMenuMapper foodMenuMapper;
    private final DeliveryTaskTemplateMapper deliveryTaskTemplateMapper;
    private final DeliveryTaskMapper deliveryTaskMapper;

    @Transactional(rollbackFor = ModifyFailureException.class)
    public void assignCompaniesToTenant(String tenantId, List<String> companyIds) {
        if (CollectionUtils.isEmpty(companyIds)) {
            log.warn("/assignCompaniesToTenant, companyIds is empty");
            throw new IllegalArgumentException("选中的公司 ID 列表不能为空");
        }

        // 校验目标租户是否存在，不存在时给出提示信息
        LambdaQueryWrapper<Tenant> queryWrapper = new LambdaQueryWrapper<Tenant>()
                .eq(Tenant::getId, tenantId);
        if (!tenantMapper.exists(queryWrapper)) {
            log.warn("/assignCompaniesToTenant, tenantId: {}, not exists", tenantId);
            throw new IllegalArgumentException("ID 为 " + tenantId + " 的租户不存在，请联系管理员排查");
        }

        // 1. 将待转让的公司的 tenantId 更新为新的租户 ID
        // UPDATE company SET tenant_id = #{tenantId} WHERE id IN (#{companyIds}...)
        LambdaUpdateWrapper<Company> updateWrapper = new LambdaUpdateWrapper<Company>()
                .in(Company::getId, companyIds);
        Company company = new Company();
        company.setTenantId(tenantId);
        int updateCount = companyMapper.update(company, updateWrapper);
        log.info("/assignCompaniesToTenant, update count: {}", updateCount);
        if (updateCount <= 0) {
            throw new ModifyFailureException("分配公司失败，请联系管理员排查");
        }

        // 2. 更新 food_menu 表中，对应公司的租户 ID 为新的租户 ID
        LambdaQueryWrapper<FoodMenu> foodMenuLambdaQueryWrapper = new LambdaQueryWrapper<FoodMenu>()
                .eq(FoodMenu::getDelFlag, false)
                .in(FoodMenu::getCompanyId, companyIds)
                .select(FoodMenu::getId, FoodMenu::getTenantId);
        List<FoodMenu> foodMenuList = foodMenuMapper.selectList(foodMenuLambdaQueryWrapper);
        // 记录一下更新前的数据，防止出现错误时可以通过日志进行回滚记录
        log.info("/assignCompaniesToTenant, 待更新的 food_menu 列表为: {}", JSONObject.toJSONString(foodMenuList));
        List<String> foodMenuIdList = foodMenuList.stream()
                .map(FoodMenu::getId)
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(foodMenuIdList)) {
            log.info("/assignCompaniesToTenant, 将 companyId 列表为 {} 对应的 food_menu 的 tenantId 更新为: {}，待更新的 food_menu ID 列表为: {}", companyIds, tenantId, foodMenuIdList);
            // 如果未删除且与公司绑定的 food_menu 记录存在，则更新 food_menu 表中对应记录的 tenant_id 为新的租户 ID
            LambdaUpdateWrapper<FoodMenu> foodMenuUpdateWrapper = new LambdaUpdateWrapper<FoodMenu>()
                    .in(FoodMenu::getId, foodMenuIdList);
            FoodMenu foodMenu = new FoodMenu();
            foodMenu.setTenantId(tenantId);
            int foodMenuUpdateCount = foodMenuMapper.update(foodMenu, foodMenuUpdateWrapper);
            if (foodMenuUpdateCount != foodMenuIdList.size()) {
                // 如果更新的记录数和查询到需要更新的记录数不一致，记录日志并触发回滚
                log.error("/assignCompaniesToTenant, update food_menu count: {}, foodMenuIdList size: {}, foodMenuIdList: {}", foodMenuUpdateCount, foodMenuIdList.size(), foodMenuIdList);
                throw new ModifyFailureException("分配公司失败，请联系管理员排查");
            }

            log.warn("/assignCompaniesToTenant, update food_menu count: {}", foodMenuUpdateCount);
        }

        // 3. 更新每个公司对应的配送任务模板和配送任务记录中的租户 ID 为新的租户 ID
        for (String companyId : companyIds) {
            LambdaQueryWrapper<DeliveryTaskTemplate> deliveryTaskTemplateLambdaQueryWrapper = new LambdaQueryWrapper<DeliveryTaskTemplate>()
                    .eq(DeliveryTaskTemplate::getCompanyId, companyId)
                    .eq(DeliveryTaskTemplate::getDelFlag, false)
                    .select(DeliveryTaskTemplate::getId, DeliveryTaskTemplate::getTenantId);
            List<DeliveryTaskTemplate> deliveryTaskTemplateList = deliveryTaskTemplateMapper.selectList(deliveryTaskTemplateLambdaQueryWrapper);
            // 记录一下更新前的数据，防止出现错误时可以通过日志进行回滚记录
            log.info("/assignCompaniesToTenant, 待更新的 deliveryTaskTemplate 列表为: {}", JSONObject.toJSONString(deliveryTaskTemplateList));
            List<String> deliveryTaskTemplateIdList = deliveryTaskTemplateList.stream()
                    .map(DeliveryTaskTemplate::getId)
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(deliveryTaskTemplateIdList)) {
                log.info("/assignCompaniesToTenant, 将 companyId 为 {} 对应的配送任务模板的 tenantId 更新为: {}，待更新的配送任务模板 ID 列表为: {}", companyId, tenantId, deliveryTaskTemplateIdList);
                // 如果该公司设置了配送任务模板，则将配送任务模板中的 tenant_id 更新为新的租户 ID
                LambdaUpdateWrapper<DeliveryTaskTemplate> deliveryTaskTemplateUpdateWrapper = new LambdaUpdateWrapper<DeliveryTaskTemplate>()
                        .in(DeliveryTaskTemplate::getId, deliveryTaskTemplateIdList);
                DeliveryTaskTemplate deliveryTaskTemplate = new DeliveryTaskTemplate();
                deliveryTaskTemplate.setTenantId(tenantId);
                int deliveryTaskTemplateUpdateCount = deliveryTaskTemplateMapper.update(deliveryTaskTemplate, deliveryTaskTemplateUpdateWrapper);
                if (deliveryTaskTemplateUpdateCount != deliveryTaskTemplateIdList.size()) {
                    // 如果更新的记录数和查询到需要更新的记录数不一致，记录日志并触发回滚
                    log.error("/assignCompaniesToTenant, update delivery_task_template_t count: {}, deliveryTaskTemplateIdList size: {}, deliveryTaskTemplateIdList: {}", deliveryTaskTemplateUpdateCount, deliveryTaskTemplateIdList.size(), deliveryTaskTemplateIdList);
                    throw new ModifyFailureException("分配公司失败，请联系管理员排查");
                }

                log.warn("/assignCompaniesToTenant, update delivery_task_template_t count: {}", deliveryTaskTemplateUpdateCount);

                // 4. 更新执行转让操作当天及以后的配送任务实例的租户 ID 为新的租户 ID
                String todayDate = DateTimeUtil.getCurrentDate();
                LambdaQueryWrapper<DeliveryTask> deliveryTaskLambdaQueryWrapper = new LambdaQueryWrapper<DeliveryTask>()
                        .in(DeliveryTask::getTaskTemplateId, deliveryTaskTemplateIdList)
                        .eq(DeliveryTask::getDelFlag, false)
                        // 配送任务状态为 "未完成" 并且配送日期在今天及以后的配送任务实例记录
                        .eq(DeliveryTask::getDeliveryStatus, 1)
                        .ge(DeliveryTask::getDeliveryDate, todayDate)
                        .select(DeliveryTask::getId, DeliveryTask::getTenantId);
                List<DeliveryTask> deliveryTaskList = deliveryTaskMapper.selectList(deliveryTaskLambdaQueryWrapper);
                // 记录一下更新前的数据，防止出现错误时可以通过日志进行回滚记录
                log.info("/assignCompaniesToTenant, 待更新的 deliveryTask 列表为: {}", JSONObject.toJSONString(deliveryTaskList));
                List<String> deliveryTaskIdList = deliveryTaskList.stream()
                        .map(DeliveryTask::getId)
                        .collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(deliveryTaskIdList)) {
                    log.info("/assignCompaniesToTenant, 将 companyId 为 {} 对应的配送任务实例的 tenantId 更新为: {}，待更新的配送任务实例 ID 列表为: {}", companyId, tenantId, deliveryTaskIdList);
                    // 如果该公司设置了配送任务模板，则将配送任务模板中的 tenant_id 更新为新的租户 ID
                    LambdaUpdateWrapper<DeliveryTask> deliveryTaskUpdateWrapper = new LambdaUpdateWrapper<DeliveryTask>()
                            .in(DeliveryTask::getId, deliveryTaskIdList);
                    DeliveryTask deliveryTask = new DeliveryTask();
                    deliveryTask.setTenantId(tenantId);
                    int deliveryTaskUpdateCount = deliveryTaskMapper.update(deliveryTask, deliveryTaskUpdateWrapper);
                    if (deliveryTaskUpdateCount != deliveryTaskIdList.size()) {
                        // 如果更新的记录数和查询到需要更新的记录数不一致，记录日志并触发回滚
                        log.error("/assignCompaniesToTenant, update delivery_task_t count: {}, deliveryTaskIdList size: {}, deliveryTaskIdList: {}", deliveryTaskUpdateCount, deliveryTaskIdList.size(), deliveryTaskIdList);
                        throw new ModifyFailureException("分配公司失败，请联系管理员排查");
                    }

                    log.warn("/assignCompaniesToTenant, update delivery_task_t count: {}", deliveryTaskUpdateCount);
                }

            }

        }

        // TODO: 更新公司对应的外卖柜记录
    }
}
